﻿using DataModels.Entities.Base;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using SEGIService.SGModel;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Emit;
using System.Security.Cryptography;
using System.Security.Policy;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using static SEGIService.SGModel.SigeCommunityResult;

namespace SEGIService.Service.Basic.Project
{
    public class SigeCommunitySyncService(SqlSugarClient db, ILogger<SigeCommunitySyncService> logger, IConfiguration config) : SEGIBaseService(db)
    {
        private readonly ILogger<SigeCommunitySyncService> _logger = logger;
        private readonly IConfiguration _config = config;

        // 这里写同步方法
        public async Task SyncCommunityDataAsync(CancellationToken cancellationToken)
        {
            try
            {

               await UpdateProjectList();

                _logger.LogInformation("同步社区数据完成");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "同步四格社区数据失败");
            }
        }

        /// <summary>
        /// 从四格获取全部项目信息
        /// </summary>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public async Task<List<CommunityItem>> FetchAllCommunityItemsAsync(int pageSize = 80)
        {
            var allItems = new List<CommunityItem>();
            int pageNo = 1;
            int totalCount = int.MaxValue;

            while (allItems.Count < totalCount)
            {
                var bodyObject = new
                {
                    communityCode = "",
                    communityName = "",
                    pageNo,
                    pageLength = pageSize,
                    topOrganId = "1"
                };

                string json = string.Empty;

                int retry = 0;
                while (retry < 3)
                {
                    try
                    {
                        json = await SendRequestAsync("v1/sync/queryCommunityListPage", bodyObject);
                        break;
                    }
                    catch (Exception ex)
                    {
                        retry++;
                        if (retry >= 3) throw;
                        await Task.Delay(1000);
                    }
                }

                var result = JsonConvert.DeserializeObject<ApiResponse>(json);

                if (result.Code != "0")
                {
                    throw new Exception($"接口返回失败：{result.Message}");
                }

                totalCount = result.Paginator.TotalCount;

                if (result.Data != null)
                    allItems.AddRange(result.Data);

                Console.WriteLine($"已拉取第 {pageNo} 页，共 {totalCount} 条记录,已经获取{allItems.Count}条数据");
                pageNo++;

                await Task.Delay(200); // 防止过快请求
            }

            return allItems;
        }

        /// <summary>
        /// 更新全部项目
        /// </summary>
        /// <returns></returns>
        private async Task UpdateProjectList()
        {
            var data = await FetchAllCommunityItemsAsync();
            var projectList = db.Queryable<Projects>().ToList();
            var existingCommunityIds = new HashSet<string>(projectList.Select(p => p.CommunityId));

            var toAdd = new List<Projects>();
            var toUpdate = new List<Projects>();

            foreach (var item in data)
            {
                if (existingCommunityIds.Contains(item.CommunityId))
                {
                    var existing = projectList.First(p => p.CommunityId == item.CommunityId);
                    // 更新 existing 的属性
                    existing.ProjectName = item.CommunityName;
                    existing.UpdatedAt = DateTime.Now;
                    toUpdate.Add(existing);
                }
                else
                {
                    var newProject = new Projects
                    {
                        UUID = Guid.NewGuid(),
                        ProjectName = item.CommunityName,
                        CommunityId = item.CommunityId,
                        UpdatedAt = DateTime.Now,
                        CreatedAt = DateTime.Now,
                    };
                    toAdd.Add(newProject);
                }
            }

            // 批量插入和更新（使用 SqlSugar 批量接口）
            if (toAdd.Count > 0)
                db.Insertable(toAdd).ExecuteCommand();

            if (toUpdate.Count > 0)
                db.Updateable(toUpdate).ExecuteCommand();
        }

 



        private async Task UpdateProject()
        {
            var baseCode = _config["SigeApi:baseCode"];

            var projectList = db.Queryable<Projects>().ToList();

            foreach (var project in projectList)
            {
                var bodyObject = new
                {
                    baseCode = baseCode,
                    communityId = 67
                    //communityId = int.Parse(project.CommunityId)
                };
                var json = await SendRequestAsync("restful/segi/masterdatasvr/querycommunity/CommunityIRestful/getCommunityDetailById", bodyObject);
            }
        }




        private async Task UpdateWorkerInof()
        {
            var baseCode = _config["SigeApi:baseCode"];
            var bodyObject = new
            {
                baseCode = baseCode,
                organId = 1
            };
            var json = await SendRequestAsync("getWorkerInofByOrganId", bodyObject);
        }


        #region 房屋信息

        /// <summary>
        /// 根据房屋id获取客户基本信息
        /// </summary>
        /// <param name="communityId"></param>
        /// <param name="houseId">房屋Id</param>
        /// <returns></returns>
        private async Task GetCustInfoByHouseId(string communityId, int houseId)
        {
            var baseCode = _config["SigeApi:baseCode"];
            var bodyObject = new
            {
                baseCode = baseCode,
                communityId,
                houseId
            };
            var json = await SendRequestAsync("getCustInfoByHouseId", bodyObject);
        }

        #endregion

        #region 员工信息

        /// <summary>
        /// 根据机构获取员工信息
        /// </summary>
        /// <param name="organId">组织机构ID</param>
        /// <returns></returns>
        private async Task GetWorkerInofByOrganId(int organId)
        {
            var baseCode = _config["SigeApi:baseCode"];
            var bodyObject = new
            {
                baseCode = baseCode,
                organId
            };
            var json = await SendRequestAsync("getWorkerInofByOrganId", bodyObject);
        }

        #endregion

        #region 客户信息


        /// <summary>
        /// 根据手机号码获取客户基本信息V3
        /// </summary>
        /// <param name="communityId">项目ID</param>
        /// <param name="phone">手机号</param>
        /// <returns></returns>
        private async Task GetCustInfoByPhone(string communityId, string phone)
        {
            var baseCode = _config["SigeApi:baseCode"];
            var bodyObject = new
            {
                baseCode = baseCode,
                communityId,
                phone
            };
            var json = await SendRequestAsync("restful/segi/masterdatasvr/querycuster/CusterIRestful/getCustInfoByPhoneV3", bodyObject);
        }

        /// <summary>
        /// 根据客户ID获取客户及成员信息（根据客户ID获取客户及成员信息）
        /// </summary>
        /// <param name="communityId">项目ID</param>
        /// <param name="custID">客户ID</param>
        /// <param name="thirdCustId">第三方客户ID</param>
        /// <returns></returns>
        private async Task GetCusterInofByCustId(int communityId, int custID, string thirdCustId)
        {
            var baseCode = _config["SigeApi:baseCode"];
            var bodyObject = new
            {
                baseCode = baseCode,
                communityId,
                custID,
                thirdCustId
            };
            var json = await SendRequestAsync("restful/segi/masterdatasvr/querycuster/CusterIRestful/getCusterInofByCustIdV2", bodyObject);
        }

        /// <summary>
        /// 根据项目ID和手机号获取客户房屋信息
        /// </summary>
        /// <param name="communityId">项目ID</param>
        /// <param name="telephone">手机号</param>
        /// <returns></returns>
        private async Task GetCustomHouseInfoByTelephone(int communityId, string telephone)
        {
            var baseCode = _config["SigeApi:baseCode"];
            var bodyObject = new
            {
                baseCode = baseCode,
                communityId,
                telephone
            };
            var json = await SendRequestAsync("getCustomHouseInfoByTelephone", bodyObject);
        }

        #endregion

        #region 客户服务

        public class ServiceOrderDto
        {

            /// <summary>
            /// 起始时间（yyyy-MM-dd） 【必填】
            /// </summary>
            public string beginTime { get; set; }

            /// <summary>
            /// 联系电话（联系电话，客户ID、房屋或联系电话必填其一。）
            /// </summary>
            public string contactTel { get; set; }

            /// <summary>
            /// 传四格系统的客户ID
            /// </summary>
            public string custId { get; set; }

            /// <summary>
            /// 第三方项目ID
            /// </summary>
            public string eCommunityId { get; set; }

            /// <summary>
            /// 终止时间（yyyy-MM-dd） 【必填】
            /// </summary>
            public string endTime { get; set; }

            /// <summary>
            /// 传四格系统的房屋ID
            /// </summary>
            public string houseId { get; set; }

            /// <summary>
            /// 项目ID（真实小区ID）
            /// </summary>
            public string main_segi_community_id { get; set; }

            /// <summary>
            /// 组织机构ID（与eCommunityId和main_segi_community_id 必填其一）
            /// </summary>
            public string main_segi_organ_id { get; set; }

            /// <summary>
            /// 公众号唯一标识（如果项目只有公众号录单，可传此值，否则无法获取其他渠道录单数据
            /// </summary>
            public string openId { get; set; }

            /// <summary>
            /// 每页显示条数 【必填】
            /// </summary>
            public string pageLength { get; set; }

            /// <summary>
            /// 页码 【必填】
            /// </summary>
            public string pageNo { get; set; }

            /// <summary>
            /// 工单状态（参考《环节(状态)编码》）
            /// </summary>
            public string serviceOrderState { get; set; }

            /// <summary>
            /// 服务类型编码
            /// </summary>
            public string serviceTypeCode { get; set; }
        }

        /// <summary>
        /// 获取客户提交过的工单
        /// </summary>
        /// <param name="orderDto"></param>
        /// <returns></returns>
        private async Task GetCustServiceInfoByCustId(ServiceOrderDto orderDto)
        {
            var json = await SendRequestAsync("v2/serviceOrder/queryServiceOrderByCust", orderDto);
        }
        #endregion

        #region 客户与房屋


        /// <summary>
        /// 根据客户ID获取房屋信息
        /// </summary>
        /// <param name="communityId">项目ID</param>
        /// <param name="custId">客户ID</param>
        /// <returns></returns>
        private async Task GetHouseInfoByCustId(int communityId, int custId)
        {
            var baseCode = _config["SigeApi:baseCode"];
            var bodyObject = new
            {
                baseCode = baseCode,
                communityId,
                custId
            };
            var json = await SendRequestAsync("restful/segi/masterdatasvr/querycuster/CusterIRestful/getHouseInfoByCustIdV2", bodyObject);
        }
        #endregion




        /// <summary>
        /// 发送请求到四格API
        /// </summary>
        /// <param name="urlName"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        private async Task<string> SendRequestAsync(string urlName, object data)
        {
            var apiUrl = _config["SigeApi:CommunitySyncUrl"];
            var appKey = _config["SigeApi:appKey"];
            var baseCode = _config["SigeApi:baseCode"];
            var secret = _config["SigeApi:secret"];
            string url = apiUrl + urlName;

            string timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
            var bodyObject = new
            {
                appKey,
                requestTime = timestamp,
                requestId = timestamp,
                noncestr = timestamp,
                apiVersion = "",
                data
            };
            return await GetSEGEResponse(url, appKey, baseCode, secret, bodyObject);
        }



        private async Task<string> GetSEGEResponse(string url, string appKey, string baseCode, string secret, object bodyObject)
        {
            // 序列化为 JSON
            string jsonBody = JsonConvert.SerializeObject(bodyObject);

            // 生成签名
            string signature = GenerateSignature(jsonBody, secret);

            using var client = new HttpClient();
            var request = new HttpRequestMessage(HttpMethod.Post, url);

            // 添加请求头
            request.Headers.Add("signature", signature);
            request.Headers.Add("appkey", appKey);
            request.Headers.Add("basecode", baseCode);

            // 设置请求体
            request.Content = new StringContent(jsonBody, Encoding.UTF8, "application/json");

            var response = await client.SendAsync(request);
            return await response.Content.ReadAsStringAsync();
        }

        /// <summary>
        /// 计算签名
        /// </summary>
        /// <param name="jsonBody"></param>
        /// <param name="secretKey"></param>
        /// <returns></returns>
        private string GenerateSignature(string jsonBody, string secretKey)
        {
            string rawString = jsonBody + "|" + secretKey;

            using var md5 = MD5.Create();
            byte[] bytes = Encoding.UTF8.GetBytes(rawString);
            byte[] hash = md5.ComputeHash(bytes);

            StringBuilder sb = new StringBuilder();
            foreach (byte b in hash)
                sb.Append(b.ToString("x2")); // 小写

            return sb.ToString();
        }
    }
}
